﻿using System;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Telerik.Windows.Controls;

namespace ManoMachine.IDE
{
    #region

    using System.ComponentModel;
    using System.Windows;

    using ManoMachine.IDE.ViewModel;

    #endregion

    /// <summary>
    ///   Interaction logic for Shell.xaml
    /// </summary>
    public partial class Shell : Window, INotifyPropertyChanged
    {
        #region Constants and Fields

        private ShellViewModel viewModel;
        const string CommentReg = @"/.*";
        const string LabelReg = "\\b([a-zA-Z][a-zA-Z0-9]?[a-zA-Z0-9]?),";
        const string NumberReg = " -?[0-9]+";

        #endregion

        #region Constructors and Destructors

        public Shell()
        {
            this.ViewModel = new ShellViewModel();
            this.ViewModel.PropertyChanged += SetSartAddress;
            this.InitializeComponent();

            RichTextBox control = (RichTextBox)this.sourceCodeContent.Child;
            control.Text =
                @"	ORG 100
	LDA SUB
	CMA
	INC
	ADD MIN
	STA DIF
	HLT
MIN, DEC 83
SUB, DEC -23
DIF, HEX 0
	END";
            this.ViewModel.SourceCodeContainer = (RichTextBox)this.sourceCodeContent.Child;
        }

        private void SetSartAddress(object sender, PropertyChangedEventArgs e)
        {
            if(e.PropertyName == "StartMemoryItem")
            {
                memoryMapGrid.ScrollIntoView(this.ViewModel.StartMemoryItem);
            }
        }

        #endregion

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        public ShellViewModel ViewModel
        {
            get
            {
                return this.viewModel;
            }
            set
            {
                this.viewModel = value;
                this.OnPropertyChanged("ViewModel");
            }
        }

        #endregion

        #region Methods

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        private void SourceCodeChanged(object sender, System.EventArgs e)
        {
            var richTextBox = (RichTextBox) sender;
            if (syntaxCheck.IsChecked == true)
            {
                SyntaxHiliting(richTextBox);
            }
            richTextBox.ForeColor = Color.Black;
        }

        private void SyntaxHiliting(RichTextBox textbBox)
        {
            // hilight numbers
            this.Highlight(textbBox, Color.Red, NumberReg);

            // hilight label
            this.Highlight(textbBox, Color.Blue, LabelReg);

            // hilight commet
            this.Highlight(textbBox, Color.Green, CommentReg);
        }

        private void CompilerClicked(object sender, RoutedEventArgs e)
        {
            this.ViewModel.BuildCommandExecute();
        }

        private void EmulateClicked(object sender, RoutedEventArgs e)
        {
            this.ViewModel.EmulateCommandExecute();
        }

        private void Highlight(RichTextBox richTextBox, Color color, string regex)
        {
            MatchCollection matches = Regex.Matches(richTextBox.Text, regex);
            richTextBox.ScrollBars = RichTextBoxScrollBars.Both;
            int selectionStart = richTextBox.SelectionStart;
            int selectionLength = richTextBox.SelectionLength;
            Color selectionColor = richTextBox.SelectionColor;

            foreach (Match matche in matches)
            {
                richTextBox.SelectionStart = matche.Index;
                richTextBox.SelectionLength = matche.Length;
                richTextBox.SelectionColor = color;
            }

            richTextBox.SelectionStart = selectionStart;
            richTextBox.SelectionLength = selectionLength;
            richTextBox.SelectionColor = selectionColor;
        }

        private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
        }

        private void ExamplesSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
        }

        private void RunToEndClick(object sender, RoutedEventArgs e)
        {
            if (this.ViewModel.CurrentEmulator.IsHalted)
            {
                RadWindow.Alert("Current Program was Halted");
                return;
            }

            this.ViewModel.CurrentEmulator.RunToEnd();
        }

        private void NextStepClicked(object sender, RoutedEventArgs e)
        {
            if (this.ViewModel.CurrentEmulator.IsHalted)
            {
                RadWindow.Alert("Current Program was Halted");
                return;
            }

            this.ViewModel.CurrentEmulator.NextStep();
        }
    }
}